<template>
  <div class="title">
    <i @click="emit('exit')" class="iconfont icon-fanhui"/>
    <div class="text">
      {{props.mode}}
    </div>
  </div>
  <div class="content" style="flex-grow: 1;">
    <el-input
        v-model="inputText"
        :autosize="{ minRows: 6, maxRows: 6 }"
        type="textarea"
        :placeholder="`请输入要${(()=>{
          switch(props.mode){
            case '文章续写':
              return '续写'
            case '文本改写':
              return '改写'
            case '文本纠错':
              return '纠错'
            case '补全段落':
              return '补全'
          }
        })()}的文本`"
    />
    <div @click="submit" :class="`btn ${isGenerating?'disabled':''}`">
      提交
    </div>
    <div v-show="isGenerating||genRes" class="generate-container" ref="generateContainerContainer">
      <div class="title" ref="titleContainer">生成内容</div>
      <div class="generate-content" ref="generateContentContainer">
        <div style="word-break: break-all;white-space: pre-line;">
          {{showText}}
          <span class="blink" v-if="isGenerating">
            _
          </span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import {nextTick, onMounted, onUnmounted, ref, watch} from 'vue'
import {generate} from '../utils/index.js'

const props = defineProps(['mode'])
const emit = defineEmits(['exit'])
const inputText = ref('')
const isGenerating = ref(false)
const genRes = ref('')
const showText = ref('')
function submit(){
  if(!isGenerating.value){
    showText.value = ''
    genRes.value = ''
    isGenerating.value = true
    generate((()=>{
      switch(props.mode){
        case '文章续写':
          return 'continuation'
        case '文本改写':
          return 'rewrite'
        case '文本纠错':
          return 'check'
        case '补全段落':
          return 'completion'
      }
    })(), {text: inputText.value}, (e) => {
      genRes.value += e
    }, () => {
      isGenerating.value = false
    })
  }
}

let intervalId = null;
watch(isGenerating,()=>{
  if (isGenerating.value) {
    let len = 0;
    let tmp_gen_len
    let last_gen_len = 0
    if (intervalId !== null) {
      clearInterval(intervalId);
    }
    intervalId = setInterval(() => {
      if (len < tmp_gen_len) {
        showText.value += genRes.value.slice(len, tmp_gen_len);
        len = tmp_gen_len;
      }
      if (len < genRes.value.length) {
        showText.value += genRes.value.slice(len, len + 1);
        len++;
      }
      if (genRes.value.length !== last_gen_len) {
        tmp_gen_len = last_gen_len
        last_gen_len = genRes.value.length
      }
    }, 100);
  }else{
    clearInterval(intervalId);
  }
})
const generateContentContainer = ref(null)
const titleContainer = ref(null)
const generateContainerContainer = ref(null)
onMounted(()=>{
  watch(()=>{return isGenerating.value||genRes.value},()=>{
    nextTick(()=>{
      generateContentContainer.value.style.height = `${generateContainerContainer.value.clientHeight - titleContainer.value.offsetHeight - 10}px`
    })
  })
})
onUnmounted(()=>{
  clearInterval(intervalId);
})
</script>

<style lang="scss" scoped>
.title{
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  .icon-fanhui{
    margin-left: 1em;
    position: absolute;
    left: 0;
    cursor: pointer;
    width: fit-content;
  }
  .text{
    font-size: 1.2em;
    font-weight: 700;
  }
}
.content{
  padding: 1em 2em 0;
  display: flex;
  flex-direction: column;
  .btn{
    margin-top: 1em;
    font-size: .9em;
    padding: .4em 1em;
    border: 1px solid #dfdfdf;
    border-radius: .5em;
    color: white;
    background: #409eff;
    cursor: pointer;
    transition: .2s linear;
    &:hover{
      background: #3375b9;
    }
    &.disabled{
      background: #3375b9;
      cursor: not-allowed;
    }
  }
  .generate-container{
    flex-grow: 1;
    .title{
      display: flex;
      justify-content: left;
      font-size: .9em;
      font-weight: 700;
      padding: .6em 0;
    }
    .generate-content{
      box-sizing: border-box;
      overflow-y: auto;
      border: 1px #e6e6e6 solid;
      border-radius: 8px;
      padding: 5px 8px;
      text-align: left;
      font-size: .9em;
    }
  }
}
</style>
